extension SetExt on Set {
  bool contentEquals(Set other) {
    if (identical(this, other)) return true;
    if (length != other?.length) return false;
    return this.containsAll(other);
  }

  int get contentHashCode => inorderedHashCode;
}

extension ListExt on List {

  bool contentEquals(List other) {
    if (identical(this, other)) return true;
    if (length != other?.length) return false;
    Iterator iter = other.iterator;
    for(dynamic e in this) {
      iter.moveNext();
      if (e != iter.current) {
        return false;
      }
    }
    return true;
  }

  int get contentHashCode => inorderedHashCode;
}

extension IterableExt on Iterable {
  int get inorderedHashCode {
    var hashCode = 0;
    for (dynamic element in this) {
      hashCode += (element?.hashCode ?? 0);
    }
    return hashCode;
  }

  int get orderedHashCode {
    var hashCode = 1;
    for (dynamic e in this) {
      hashCode = 31 * hashCode + (e?.hashCode ?? 0);
    }
    return hashCode;
  }
}